<!DOCTYPE html>
            
<HTML>
<HEAD>
<meta name="booktitle" content="Developing Applications With Objective Caml" >
 <meta charset="ISO-8859-1"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<META name="GENERATOR" content="hevea 1.05-7 of 2000-02-24">
<META NAME="Author" CONTENT="Christian.Queinnec@lip6.fr">
<LINK rel=stylesheet type="text/css" href="videoc-ocda.css">
<script language="JavaScript" src="videoc.js"><!--
//--></script>
<TITLE>
 Desktop Calculator
</TITLE>
</HEAD>
<BODY class="regularBody">
<A HREF="book-ora018.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora020.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2> Desktop Calculator</H2>To understand how a program is built in
Objective CAML, it is necessary to develop one. The chosen example is a
desktop calculator---that is, the simplest model, which only works on whole
numbers and only carries out the four standard arithmetic operations. <BR>
<BR>
To begin, we define the type <I>key</I> to represent the keys of a
pocket calculator. The latter has fifteen keys, namely: one for each
operation, one for each digit, and the <TT>=</TT> key.


<PRE><BR># <B>type</B><CODE> </CODE>key<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Plus<CODE> </CODE><CODE>|</CODE><CODE> </CODE>Minus<CODE> </CODE><CODE>|</CODE><CODE> </CODE>Times<CODE> </CODE><CODE>|</CODE><CODE> </CODE>Div<CODE> </CODE><CODE>|</CODE><CODE> </CODE>Equals<CODE> </CODE><CODE>|</CODE><CODE> </CODE>Digit<CODE> </CODE><B>of</B><CODE> </CODE>int<CODE> </CODE>;;<BR>

</PRE>

We note that the numeric keys are gathered under a single constructor
Digit taking an integer argument. In fact, some values of type
<I>key</I> don't actually represent a key. For example, <TT>(</TT>Digit<CODE> </CODE><CODE>3</CODE><CODE>2</CODE><TT>)</TT>
is a possible value of type <I>key</I>, but doesn't represent any of
the calculator's keys.<BR>
<BR>
So we write a function <TT>valid</TT> which verifies that its argument
corresponds to a calculator key. The type of this function is <I>key
-&gt; bool</I>, that is, it takes a value of type <I>key</I> as argument and
returns a value of type <I>bool</I>.<BR>
<BR>
The first step is to define a function which verifies that an integer is
included between 0 and 9. We declare this function under the name 
<TT>is_digit</TT>:


<PRE><BR># <B>let</B><CODE> </CODE>is_digit<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT>x<CODE>&gt;=</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><CODE>&amp;&amp;</CODE><CODE> </CODE><TT>(</TT>x<CODE>&lt;=</CODE><CODE>9</CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>val is_digit : int -&gt; bool = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
We then define the function <TT>valid</TT> by pattern-matching over its
argument of type <I>key</I>:


<PRE><BR># <CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>valid<CODE> </CODE>ky<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>match</B><CODE> </CODE>ky<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Digit<CODE> </CODE>n<CODE> </CODE>-&gt;<CODE> </CODE>is_digit<CODE> </CODE>n<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE><B>true</B><CODE> </CODE>;;<BR><CODE>val valid : key -&gt; bool = &lt;fun&gt;</CODE><BR>

</PRE>

The first pattern is applied when the argument of <TT>valid</TT> is a value
made with the Digit constructor; in this case, the argument of
Digit is tested by the function <TT>is_digit</TT>. The second
pattern is applied to every other kind of value of type <I>key</I>.
Recall that thanks to typing, the value being matched is necessarily of
type <I>key</I>.<BR>
<BR>
Before setting out to code the calculator mechanism, we will specify a
model allowing us to describe from a formal point of view the reaction to
the activation of one of the device's keys. We will consider a pocket
calculator to have four registers in which are stored respectively the last
computation done, the last key activated, the last operator
activated, and the number printed on the screen. The set of these four
registers is called the state of the calculator; it is modified by each
keypress on the keypad. This modification is called a transition and the
theory governing this kind of mechanism is that of automata. A state will
be represented in our program by a record type:


<PRE><BR># <B>type</B><CODE> </CODE>state<CODE> </CODE><CODE>=</CODE><CODE> </CODE>{<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>lcd<CODE> </CODE><CODE>:</CODE><CODE> </CODE>int;<CODE> </CODE><CODE>(* last computation done   *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>lka<CODE> </CODE><CODE>:</CODE><CODE> </CODE>key;<CODE> </CODE><CODE>(* last key activated      *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>loa<CODE> </CODE><CODE>:</CODE><CODE> </CODE>key;<CODE> </CODE><CODE>(* last operator activated *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>vpr<CODE> </CODE><CODE>:</CODE><CODE> </CODE>int<CODE> </CODE><CODE> </CODE><CODE>(* value printed           *)</CODE><BR><CODE> </CODE>}<CODE> </CODE>;;<BR>

</PRE>
<BR>
<BR>
Figure <A HREF="book-ora019.html#fig-ex-transit">2.6</A> gives an example of a sequence of transitions.
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>state</TD>
<TD  ALIGN=left NOWRAP>key</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>(0,=,=,0)</TD>
<TD  ALIGN=left NOWRAP>3</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><FONT FACE=symbol>��</FONT></TD>
<TD  ALIGN=left NOWRAP>(0,3,=,3)</TD>
<TD  ALIGN=left NOWRAP>+</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><FONT FACE=symbol>��</FONT></TD>
<TD  ALIGN=left NOWRAP>(3,+,+,3)</TD>
<TD  ALIGN=left NOWRAP>2</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><FONT FACE=symbol>��</FONT></TD>
<TD  ALIGN=left NOWRAP>(3,2,+,2)</TD>
<TD  ALIGN=left NOWRAP>1</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><FONT FACE=symbol>��</FONT></TD>
<TD  ALIGN=left NOWRAP>(3,1,+,21)</TD>
<TD  ALIGN=left NOWRAP>�</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><FONT FACE=symbol>��</FONT></TD>
<TD  ALIGN=left NOWRAP>(24,*,*,24)</TD>
<TD  ALIGN=left NOWRAP>2</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><FONT FACE=symbol>��</FONT></TD>
<TD  ALIGN=left NOWRAP>(24,2,*,2)</TD>
<TD  ALIGN=left NOWRAP>=</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><FONT FACE=symbol>��</FONT></TD>
<TD  ALIGN=left NOWRAP>(48,=,=,48)</TD>
<TD  ALIGN=left NOWRAP>&nbsp;</TD>
</TR></TABLE>
<BR>
<DIV ALIGN=center>Figure 2.6: Transitions for 3+21*2= <A NAME="fig-ex-transit"></A>.</DIV><BR>

</DIV>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>In what follows
we need the function <TT>evaluate</TT> which takes two integers and a value
of type <TT>key</TT> containing an operator and which returns the result of
the operation corresponding to the key, applied to the integers. This
function is defined by pattern-matching over its last argument, of type
<I>key</I>:


<PRE><BR># <B>let</B><CODE> </CODE>evaluate<CODE> </CODE>x<CODE> </CODE>y<CODE> </CODE>ky<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>match</B><CODE> </CODE>ky<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Plus<CODE> </CODE><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE>y<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Minus<CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE>x<CODE> </CODE><CODE>-</CODE><CODE> </CODE>y<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Times<CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE>x<CODE> </CODE><CODE>*</CODE><CODE> </CODE>y<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Div<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE>x<CODE> </CODE><CODE>/</CODE><CODE> </CODE>y<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Equals<CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE>y<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Digit<CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE>failwith<CODE> </CODE><CODE>"evaluate : no op"</CODE>;;<BR><CODE>val evaluate : int -&gt; int -&gt; key -&gt; int = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
Now we give the definition of the transition function by enumerating all
possible cases. We assume that the current state is the quadruplet
(<I>a</I>,<I>b</I>,<FONT FACE=symbol>�</FONT>,<I>d</I>):
<UL>
<LI>
  a key with digit <I>x</I> is pressed, then there are two cases to
 consider:
 <UL>
<LI>
  the last key pressed was also a digit. So it is a number which
 the user of the pocket calculator is in the midst of entering;
 consequently the digit <I>x</I> must be affixed to the printed value, i.e.,
 replacing it with <I>d</I>�10+<I>x</I>. The new state is:
 <DIV ALIGN=center>(<I>a</I>,<TT>(<I>Digit</I> <I>x</I>)</TT>,<FONT FACE=symbol>�</FONT>,<I>d</I>�10+<I>x</I>)</DIV><BR>
 
<LI> the last key pressed was not a digit. So it is the start of a new
 number which is being entered. The new state is:
 <DIV ALIGN=center>(<I>a</I>,<TT>(<I>Digit</I> <I>x</I>)</TT>,<FONT FACE=symbol>�</FONT>,<I>x</I>)</DIV> 
 </UL>
 
<LI> a key with operator <FONT FACE=symbol>�</FONT> has been pressed, the second operand
 of the operation has thus been completely entered and the calculator has
 to deal with carrying out this operation. It is to this end that the last
 operation (here <FONT FACE=symbol>�</FONT>) is stored. The new state is:
 <DIV ALIGN=center>(<FONT FACE=symbol>�</FONT> <I>d</I>,<FONT FACE=symbol>�</FONT>,<FONT FACE=symbol>�</FONT>,<I>a</I> <FONT FACE=symbol>�</FONT> <I>d</I>)</DIV>
</UL>To write the function <TT>transition</TT>, it suffices to translate
the preceding definition word for word into Objective CAML: the definition
by cases becomes a definition by pattern-matching over the key passed as an
argument. The case of a key, which itself is made up of two cases, is handled
by the local function 
<TT>digit_transition</TT> by pattern-matching over
the last key activated.


<PRE><BR># <B>let</B><CODE> </CODE>transition<CODE> </CODE>st<CODE> </CODE>ky<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>digit_transition<CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Digit<CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE>{<CODE> </CODE>st<CODE> </CODE><B>with</B><CODE> </CODE>lka<CODE>=</CODE>ky;<CODE> </CODE>vpr<CODE>=</CODE>st<CODE>.</CODE>vpr<CODE>*</CODE><CODE>1</CODE><CODE>0</CODE><CODE>+</CODE>n<CODE> </CODE>}<CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE>{<CODE> </CODE>st<CODE> </CODE><B>with</B><CODE> </CODE>lka<CODE>=</CODE>ky;<CODE> </CODE>vpr<CODE>=</CODE>n<CODE> </CODE>}<CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>ky<CODE> </CODE><B>with</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Digit<CODE> </CODE>p<CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE><CODE> </CODE>digit_transition<CODE> </CODE>p<CODE> </CODE>st<CODE>.</CODE>lka<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>res<CODE> </CODE><CODE>=</CODE><CODE> </CODE>evaluate<CODE> </CODE>st<CODE>.</CODE>lcd<CODE> </CODE>st<CODE>.</CODE>vpr<CODE> </CODE>st<CODE>.</CODE>loa<CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE>{<CODE> </CODE>lcd<CODE>=</CODE>res;<CODE> </CODE>lka<CODE>=</CODE>ky;<CODE> </CODE>loa<CODE>=</CODE>ky;<CODE> </CODE>vpr<CODE>=</CODE>res<CODE> </CODE>}<CODE> </CODE><CODE> </CODE>;;<BR><CODE>val transition : state -&gt; key -&gt; state = &lt;fun&gt;</CODE><BR>

</PRE>

This function takes a <I>state</I> and a <I>key</I> and computes the new 
<I>state</I>.<BR>
<BR>
We can now test this program on the previous example:


<PRE><BR># <B>let</B><CODE> </CODE>initial_state<CODE> </CODE><CODE>=</CODE><CODE> </CODE>{<CODE> </CODE>lcd<CODE>=</CODE><CODE>0</CODE>;<CODE> </CODE>lka<CODE>=</CODE>Equals;<CODE> </CODE>loa<CODE>=</CODE>Equals;<CODE> </CODE>vpr<CODE>=</CODE><CODE>0</CODE><CODE> </CODE>}<CODE> </CODE>;;<CODE> </CODE><BR><CODE>val initial_state : state = {lcd=0; lka=Equals; loa=Equals; vpr=0}</CODE><BR># <B>let</B><CODE> </CODE>state2<CODE> </CODE><CODE>=</CODE><CODE> </CODE>transition<CODE> </CODE>initial_state<CODE> </CODE><TT>(</TT>Digit<CODE> </CODE><CODE>3</CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>val state2 : state = {lcd=0; lka=Digit 3; loa=Equals; vpr=3}</CODE><BR># <B>let</B><CODE> </CODE>state3<CODE> </CODE><CODE>=</CODE><CODE> </CODE>transition<CODE> </CODE>state2<CODE> </CODE>Plus<CODE> </CODE>;;<BR><CODE>val state3 : state = {lcd=3; lka=Plus; loa=Plus; vpr=3}</CODE><BR># <B>let</B><CODE> </CODE>state4<CODE> </CODE><CODE>=</CODE><CODE> </CODE>transition<CODE> </CODE>state3<CODE> </CODE><TT>(</TT>Digit<CODE> </CODE><CODE>2</CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>val state4 : state = {lcd=3; lka=Digit 2; loa=Plus; vpr=2}</CODE><BR># <B>let</B><CODE> </CODE>state5<CODE> </CODE><CODE>=</CODE><CODE> </CODE>transition<CODE> </CODE>state4<CODE> </CODE><TT>(</TT>Digit<CODE> </CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>val state5 : state = {lcd=3; lka=Digit 1; loa=Plus; vpr=21}</CODE><BR># <B>let</B><CODE> </CODE>state6<CODE> </CODE><CODE>=</CODE><CODE> </CODE>transition<CODE> </CODE>state5<CODE> </CODE>Times<CODE> </CODE>;;<BR><CODE>val state6 : state = {lcd=24; lka=Times; loa=Times; vpr=24}</CODE><BR># <B>let</B><CODE> </CODE>state7<CODE> </CODE><CODE>=</CODE><CODE> </CODE>transition<CODE> </CODE>state6<CODE> </CODE><TT>(</TT>Digit<CODE> </CODE><CODE>2</CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>val state7 : state = {lcd=24; lka=Digit 2; loa=Times; vpr=2}</CODE><BR># <B>let</B><CODE> </CODE>state8<CODE> </CODE><CODE>=</CODE><CODE> </CODE>transition<CODE> </CODE>state7<CODE> </CODE>Equals<CODE> </CODE>;;<BR><CODE>val state8 : state = {lcd=48; lka=Equals; loa=Equals; vpr=48}</CODE><BR>

</PRE>
<BR>
<BR>
This run can be written in a more concise way using a function applying a
sequence of transitions corresponding to a list of keys passed as an
argument.<BR>
<BR>


<PRE><BR># <B>let</B><CODE> </CODE>transition_list<CODE> </CODE>st<CODE> </CODE>ls<CODE> </CODE><CODE>=</CODE><CODE> </CODE>List.fold_left<CODE> </CODE>transition<CODE> </CODE>st<CODE> </CODE>ls<CODE> </CODE>;;<BR><CODE>val transition_list : state -&gt; key list -&gt; state = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>example<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>[</CODE><CODE> </CODE>Digit<CODE> </CODE><CODE>3</CODE>;<CODE> </CODE>Plus;<CODE> </CODE>Digit<CODE> </CODE><CODE>2</CODE>;<CODE> </CODE>Digit<CODE> </CODE><CODE>1</CODE>;<CODE> </CODE>Times;<CODE> </CODE>Digit<CODE> </CODE><CODE>2</CODE>;<CODE> </CODE>Equals<CODE> </CODE><CODE>]</CODE><BR><CODE> </CODE><B>in</B><CODE> </CODE>transition_list<CODE> </CODE>initial_state<CODE> </CODE>example<CODE> </CODE>;;<BR><CODE>- : state = {lcd=48; lka=Equals; loa=Equals; vpr=48}</CODE><BR>

</PRE>

<BR>
<BR>
<BR>
<BR>

<BR>
<BR>
<HR>
<A HREF="book-ora018.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora020.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
